/**
 * Description: 服务端 
 * File: server.c |Time: 2021-06-28 04:40
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <string.h>
#include <strings.h>

#define BUFSIZE 128
#define ERR(msg) do{        \
    perror(msg);            \
    printf("err: %s:%s:%d\n", __FILE__, __func__, __LINE__); \
    return EXIT_FAILURE;    \
}while(0)

#define LISTEN_BACKLOG 10

int main(int argc, const char *argv[])
{
    if (argc < 3) {
        printf("Usage: %s <ip> <port>\n", argv[0]);
        return EXIT_FAILURE;
    }

    int res;
    int sockfd = socket(AF_INET, SOCK_STREAM, 0);
    const char *ip = argv[1];
    const int port = atoi(argv[2]);

    int is_reuse = 1;
    int len_is_reuse = sizeof(is_reuse);
    res = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &is_reuse, sizeof(is_reuse));
    if (res < 0) {
        ERR("setsockopt error");
    }

    if (socket < 0) {
        ERR("socket");
    }

    struct sockaddr_in serveraddr, clientaddr;
    socklen_t addrlen = sizeof(serveraddr);
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(port);
    serveraddr.sin_addr.s_addr = inet_addr(ip);
    
    res = bind(sockfd, (struct sockaddr *)&serveraddr, addrlen);
    if (res < 0) 
    {
        ERR("bind error");
    }

    res = listen(sockfd, LISTEN_BACKLOG);
    if (res < 0) {
        ERR("listen error");
    }

    int recvfd;
    pid_t pid;
    char buf[BUFSIZE] = {0};

    while(1) {
        recvfd = accept(sockfd, (struct sockaddr *)&serveraddr, &addrlen);
        if (recvfd < 0) {
            ERR("acccpt error");
        }
        printf("connected.\n");

        pid = fork();
        if (pid < 0) {
            ERR("pid error");
        }

        if (pid > 0) {
            while(1) {
                memset(buf, 0, BUFSIZE);
                res = recv(recvfd, buf, BUFSIZE, 0);

                if (res == 0) 
                {
                    printf("client exit\n");
                    break;
                }

                if(res < 0) {
                    ERR("recv error");
                }
                printf("[recv] %s\n", buf);
            }
            
        }
    }
    
    return 0;
}


